package yxy.banana.server.internal;

import yxy.apple.logger.Logger;
import yxy.apple.nio.client.Client;
import yxy.apple.util.scheduler.Schedulable;
import yxy.apple.util.scheduler.SingleThreadScheduler;
import yxy.banana.server.management.Bundled;

public class InternalClientBundler<H extends InternalClientHandler> extends Bundled<H> {
	private static final Logger logger = Logger.create(InternalClientBundler.class);
	private SingleThreadScheduler<Schedulable> scheduler = new SingleThreadScheduler<>();

	private Client client = null;
	private int interval = 10000;
	private boolean running = false;

	/**
	 * 
	 * @param client
	 * @param channels
	 * @param interval 重连尝试的周期
	 */
	public InternalClientBundler(Client client, int interval) {
		if (client == null || interval <= 0) {
			throw new IllegalArgumentException();
		} else {
			this.client = client;
		}
	}

	public void start(int connections) {
		this.running = true;
		for (int i = 0; i < connections; i++) {
			this.connect();
		}
	}

	private void connect() {
		try {
			this.client.connect();
		} catch (Exception e) {
			this.reconnect();
			logger.warn("新建或重连内部连接失败（当前%d可用），将在%d毫秒后重试...", this.bundling.size(), this.interval);
			logger.trace(e);
		}
	}

	private void reconnect() {
		if (this.running) {
			this.scheduler.schedule(new Schedulable() {
				@Override
				public void trigger() {
					InternalClientBundler.this.connect();
				}

				@Override
				public void cancelled() {
				}
			}, this.interval);
		}
	}

	public synchronized void stop() {
		this.running = false;
		for (H h : this.bundling) {
			h.disconnect();
		}
		this.client.shutdown();
		this.bundling.clear();
		this.scheduler.clear();
	}

	@Override
	public synchronized void remove(H handler) {
		super.remove(handler);
		this.reconnect();
	}

	public int activities() {
		return this.size();
	}
}
